import json
import threading
from datetime import datetime
from tkinter import scrolledtext
from tkinter.ttk import Label, Button

from util.comm.AsyncTask import AsyncTask
from util.comm.cmd_util import wrap_with_try_except
from util.comm.data_handle_util import LoadDatetime, ensure_utf8
from util.comm.msg_util import msg
from util.comm.notepad import watch_text_temp
import tkinter as tk
from util.comm.path import getConfigPath
from util.database.comm_data import query_sql
from util.window.config_window.config_button import create_config_button
from util.window.config_window.config_module import config_select, select_reload_button


class WinYwSqlData():
    def __init__(self):
        super().__init__()

    def frame(self, tab):
        config_path = getConfigPath()
        self.tabFrame(tab, config_path)

    def tabFrame(self, tab, config_path):
        self.tab = tab

        self.elements = []

        self.config_path = config_path
        self.button = create_config_button(self, True)

        # 打开文件并读取JSON数据
        with open(self.config_path, 'r', encoding="utf-8") as file:
            data = json.load(file)
        if isinstance(data, list):
            for index, c in enumerate(data):
                if 'is_active' in c:
                    if c['is_active'] == 0:
                        continue
                # 增加二级目录
                menu = self.create_tab(self.tab, c['name'])
                self.elements.append(menu)
                content = c
                cur = WinYwSqlData()
                cur.elements = self.elements
                cur.tab = menu
                cur.menuFrame(menu, content)
        else:
            print(data)

    def print_entry_sync(self, n, t, c, m):
        flag = "sync_flag_%s" % n
        if hasattr(self, flag) and getattr(self, flag) == '1':
            msg('正在处理,请勿重复操作')
            return
        setattr(self, flag, '1')
        wrap_print_entry = wrap_with_try_except(self.print_entry)
        AsyncTask(threading.Thread(target=wrap_print_entry, args=(t, c, m,)),
                  lambda n=n: self.reset_sync(n)).execute_async()

    def reset_sync(self, n):
        flag = "sync_flag_%s" % n
        setattr(self, flag, '0')

    def print_entry(self, t, c, m):
        if hasattr(t, 'label_out'):
            t.label_out.destroy()
        # 数据库配置
        dbConfig = self.dropdown.config_info
        # 替换sql中的变量,遍历map-key,value
        map = {}
        for key, value in m.items():
            v = ""
            try:
                v = value.get("1.0", "end-1c")
            except:
                pass
            map[key] = v
        conf = c['result']
        result = handle_sql_all(dbConfig, conf, map)
        result = ensure_utf8(result)
        # 对象result转json字符串，并格式化打印
        json_str = json.dumps(result, indent=4, ensure_ascii=False, cls=LoadDatetime)
        watch_text_temp(json_str, 'gbk')

        t.label_out = Label(self.tab, text="结果：已输出【%s】" % datetime.now())
        try:
            t.label_out.pack(side='bottom', fill='x')
        except:
            t.label_out.grid(column=1)

    def create_tab(self, master_tabs, title):
        # 创建第一级tab t1
        tree_tab = tk.Frame(master_tabs)
        tree_tab.pack()

        master_tabs.add(tree_tab, text=title)
        return tree_tab

    def menuFrame(self, tab, config):
        self.menu = tab
        content = config
        params = content["params"]

        self.label = Label(self.menu, text="数据源")
        self.label.grid(row=0, column=0, padx=5, pady=5)

        select_moudle = config_select(tab, None)
        self.config_select_db_button = select_reload_button().create(tab, select_moudle)

        self.dropdown = select_moudle.create(10)
        self.dropdown.grid(row=0, column=1, padx=5, pady=5)
        self.elements.append(self.dropdown)

        self.config_select_db_button.grid(row=0, column=2, padx=5, pady=5)
        self.elements.append(self.config_select_db_button)

        # 增加输入框
        map = {}
        if isinstance(params, list):
            row = 1
            for index, param in enumerate(params):
                title = param['field_title']
                field = param['field']
                w = param['width']
                h = param['height']

                # 标题
                self.label = Label(self.menu, text=title)
                self.label.grid(row=row, column=0, padx=5, pady=5)

                self.Entry = scrolledtext.ScrolledText(self.menu, width=w, height=h)
                self.Entry.grid(row=row, column=1, padx=5, pady=5)

                map[field] = self.Entry

                row += 1

                new_row = tk.Frame(self.menu)
                new_row.grid(row=row, column=0, sticky='news')

        # 增加按钮
        button = content["button"]

        self.button = Button(self.menu, text=button, command=lambda n=content["name"], t=tab, c=content, m=map: self.print_entry_sync(n, t, c, m), width=12)
        self.button.grid(row=row, column=1, padx=36, pady=5)

def createLabelOut(tab, message):
    if len(message) > 100:
        message = message[:45] + '...' + message[-45:-1]
    tab.label_out = Label(tab, text=message)
    tab.label_out.grid(column=1)

def handle_sql_all(dbConfig, conf, map):
    result = handle_sql_conf_map(dbConfig, conf, map, {})
    fields = conf['fields']
    # 判断是否是数组
    if isinstance(result, list):
        for index, item in enumerate(result):
            for k, v in fields.items():
                item[k] = handle_sql_conf_map(dbConfig, v, map, item)
    else:
        # 遍历map
        for k, v in fields.items():
            result[k] = handle_sql_conf_map(dbConfig, v, map, result)
    return result

def handle_sql_conf_map(dbConfig, conf, map, result_map):
    sql = conf['sql']
    type = conf['type']
    params = conf['params']
    param_list = []
    if ',' in params:
        param_list = params.split(',')
    else:
        param_list.append(params)
    for param in param_list:
        if param in result_map:
            sql = sql.replace(f"{{{param}}}", "'%s'" % result_map[param])
        elif param in map:
            sql = sql.replace(f"{{{param}}}", "'%s'" % map[param])
        else:
            sql = sql.replace(f"{{{param}}}", "''")
    result = query_sql(sql, dbConfig)
    if type == '1':
        # 三目如果数组长度大于1，则取第一个，否则返回空对象
        if len(result) >= 1:
            result = result[0]
        else:
            result = {}
        return result
    elif type == '2':
        # 下方显示结果
        return result
    else:
        return None